1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.testing;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.collect.Sets;
23 import com.google.common.reflect.AbstractInvocationHandler;
24 import com.google.common.reflect.Invokable;
25 import com.google.common.reflect.Parameter;
26 import com.google.common.reflect.TypeToken;
27
28 import java.io.Serializable;
29 import java.lang.reflect.Method;
30 import java.lang.reflect.Proxy;
31 import java.util.Set;
32
33 import javax.annotation.Nullable;
34
35
36
37
38
39
40 abstract class DummyProxy {
41
42
43
44
45
46 final <T> T newProxy(TypeToken<T> interfaceType) {
47 Set<Class<?>> interfaceClasses = Sets.newLinkedHashSet();
48 interfaceClasses.addAll(interfaceType.getTypes().interfaces().rawTypes());
49
50 interfaceClasses.add(Serializable.class);
51 Object dummy = Proxy.newProxyInstance(
52 interfaceClasses.iterator().next().getClassLoader(),
53 interfaceClasses.toArray(new Class<?>[interfaceClasses.size()]),
54 new DummyHandler(interfaceType));
55 @SuppressWarnings("unchecked")
56 T result = (T) dummy;
57 return result;
58 }
59
60
61 abstract <R> R dummyReturnValue(TypeToken<R> returnType);
62
63 private class DummyHandler extends AbstractInvocationHandler implements Serializable {
64 private final TypeToken<?> interfaceType;
65
66 DummyHandler(TypeToken<?> interfaceType) {
67 this.interfaceType = interfaceType;
68 }
69
70 @Override protected Object handleInvocation(
71 Object proxy, Method method, Object[] args) {
72 Invokable<?, ?> invokable = interfaceType.method(method);
73 ImmutableList<Parameter> params = invokable.getParameters();
74 for (int i = 0; i < args.length; i++) {
75 Parameter param = params.get(i);
76 if (!param.isAnnotationPresent(Nullable.class)) {
77 checkNotNull(args[i]);
78 }
79 }
80 return dummyReturnValue(interfaceType.resolveType(method.getGenericReturnType()));
81 }
82
83 @Override public int hashCode() {
84 return identity().hashCode();
85 }
86
87 @Override public boolean equals(Object obj) {
88 if (obj instanceof DummyHandler) {
89 DummyHandler that = (DummyHandler) obj;
90 return identity().equals(that.identity());
91 } else {
92 return false;
93 }
94 }
95
96 private DummyProxy identity() {
97 return DummyProxy.this;
98 }
99
100 @Override public String toString() {
101 return "Dummy proxy for " + interfaceType;
102 }
103
104
105
106 private Object writeReplace() {
107 return new DummyHandler(TypeToken.of(interfaceType.getRawType()));
108 }
109 }
110 }